﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;

namespace MWRCommunicationLibrary
{
    public interface IMWRData
    {
        /// <summary>
        /// 默认CANID
        /// </summary>
        int DefaultCanID { get; }

        /// <summary>
        /// 数据帧长度
        /// </summary>
        int Length { get; }

        void FillData(byte[] data);

        byte[] GetSender(int radarID);
    }

    public abstract class MWRData : IMWRData
    {
        public virtual int DefaultCanID
        {
            get
            {
                return -1;
            }
        }

        public virtual int Length
        {
            get
            {
                return -1;
            }
        }

        /// <summary>
        /// 根据接收到报文填充数据类实例
        /// </summary>
        /// <param name="data"></param>
        public virtual void FillData(byte[] data)
        {
            Type type = this.GetType();
            var properties = type.GetProperties();

            foreach(var p in properties)
            {
                ParamDecodorAttribute attr = (ParamDecodorAttribute)p.GetCustomAttribute(typeof(ParamDecodorAttribute));
                if(attr != null)
                {
                    var value = DecodeOperation.DecodeData(data, attr);
                    if(p.PropertyType == typeof(bool))
                    {
                        p.SetValue(this, value.Equals(1d));
                    }
                    else if(p.PropertyType == typeof(int))
                    {
                        p.SetValue(this, int.Parse(value.ToString()));
                    }
                    else if(p.PropertyType == typeof(double))
                    {
                        p.SetValue(this, double.Parse(value.ToString()));
                    }
                    
                }
            }
        }

        public virtual byte[] GetSender(int radarID)
        {
            Type type = this.GetType();
            var properties = type.GetProperties();

            //组装CANID
            byte[] msg_data = new byte[8];


            foreach (var p in properties)
            {
                ParamDecodorAttribute attr = (ParamDecodorAttribute)p.GetCustomAttribute(typeof(ParamDecodorAttribute));
                if (attr != null)
                {
                    int value = 0;
                    if (p.PropertyType == typeof(bool))
                    {
                        value = DecodeOperation.ConvertValueSender((bool)p.GetValue(this));
                    }
                    else if (p.PropertyType == typeof(int))
                    {
                        value = DecodeOperation.ConvertValueSender((int)p.GetValue(this), attr);
                    }
                    else if (p.PropertyType == typeof(double))
                    {
                        value = DecodeOperation.ConvertValueSender((double)p.GetValue(this), attr);
                    }

                    DecodeOperation.AssembleMsg(attr, value, ref msg_data);
                }
            }

            byte[] msg = new byte[13];
            int canID = this.DefaultCanID;
            canID = canID + radarID * 0x10;
            byte[] bCanID = BitConverter.GetBytes(canID);
            msg[0 + 3] = bCanID[1];
            msg[1 + 3] = bCanID[0];

            for(int i = 0;i < 8;i++)
            {
                msg[5 + i] = msg_data[i];
            }

            return msg;
        }

        /// <summary>
        /// 为报文添加Can协议头
        /// canType0  0：标准帧 1：扩展帧
        /// canType1  0：数据帧 1：远程帧
        /// </summary>
        /// <param name="canType0">帧信息</param>
        /// <param name="canType1">帧信息</param>
        /// <param name="msg"></param>
        public virtual void SetCANMsg(ref byte[] msg, int canType0 = 0, int canType1 = 0)
        {
            //第7位
            if(canType0 == 1)
            {
                msg[0] |= 0x80;
            }
            //第6位
            if(canType1 == 1)
            {
                msg[0] |= 0x40;
            }
            //数据帧长度
            msg[0] |= (byte)this.Length;
        }
        
    }
}
